/**
 * 这是 sgame 配套测试 json 编码解析器的 socket 服务器
 * 你可以直接使用 node 启动它
 * npm install
 * node server.js
 */

const WebSocket = require('ws');
const protobuf = require("protobufjs");

async function decode(data) {
    return await protobuf.load("../../proto/proto.proto").then(async (root) => {
        // Obtain a message type
        var MSG = root.lookupType("Msg");
        let msg = MSG.decode(data);
        if (!msg.data) {
            return [msg.id]
        }

        return await protobuf.load('../../assets/example/socket/proto/test.proto').then((root) => {
            var TEST_SEND_TXT = root.lookupType("TEST_SEND_TXT");
            return [msg.id, TEST_SEND_TXT.decode(msg.data)];
        });
    });
}

async function encode(protoId, data = null) {
    return await protobuf.load('../../assets/example/socket/proto/test.proto').then(async (root) => {
        var TEST_SEND_TXT = root.lookupType("TEST_SEND_TXT");
        return await protobuf.load("../../proto/proto.proto").then((root) => {
            var MSG = root.lookupType("Msg");
            let msg = {
                id: protoId
            };

            if (data) {
                msg.data = TEST_SEND_TXT.encode(data).finish();
            }

            return MSG.encode(msg).finish();
        });
    });
}

const port = 8998;

// 创建WebSocket服务器
const wss = new WebSocket.Server({ port });

let handler = new Map();
handler.set(1, async (ws, data) => {
    ws.send(await encode(1, data));
    console.log("send", 1, 'send to client: ' + data.txt);
});

handler.set(2, (ws, data) => {
    // 等待 3s 后发送
    setTimeout(async () => {
        ws.send(await encode(2, data));
        console.log("sendHalt", 2, 'send halt to client: ' + data);
    }, 3000);
});

wss.on('connection', async (ws) => {
    console.log('客户端已连接');

    // 当接收到客户端的消息时
    ws.on('message', async (message) => {
        let [protoId, data] = await decode(message);
        console.log(`接收到消息: ${protoId}, ${data}`);
        let func = handler.get(protoId);
        if (!func) {
            console.error(`没有协议: ${protoId} 处理器`);
            return;
        }

        func(ws, data);
    });

    // 发送消息到客户端
    let data = await encode(1, {
        txt: '你好！欢迎连接到WebSocket服务器。'
    });
    console.log("连接", data);
    ws.send(data);

    // 当连接关闭时
    ws.on('close', (code, reason) => {
        console.log('客户端已断开连接', code, reason);
    });
});

console.log(`WebSocket服务器正在监听端口: ${port}\n`);